home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / parse / authencrypt.c next >
Encoding:
C/C++ Source or Header  |  1995-04-19  |  11.0 KB  |  475 lines  |  [TEXT/CWIE]

  1. /*
  2.  * Authencrypt.c
  3.  * Authentication module for NCSA/Telnet and Brown tn3270.
  4.  */
  5.  
  6.  
  7.  
  8. #include "tnae.h"
  9. #include "authencrypt.h"
  10. #include "authencrypt.proto.h"
  11. #include "KrbDriver.h"
  12. #include "DlogUtils.proto.h"
  13.  
  14. #define NAUTHTYPES    10                    /* Max number of auth types */
  15.  
  16. struct codemodule *authmodules = 0;    /* list of authentication code modules */
  17.  
  18. static char nullbuf[] = {IAC, SB, OPT_AUTHENTICATION, TNQ_IS, AUTH_NULL, 
  19.                              AUTH_CLIENT_TO_SERVER|AUTH_HOW_ONE_WAY, IAC, SE};
  20.  
  21. #ifdef powerc
  22. enum {
  23.     uppModule = kCStackBased
  24.         | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  25.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
  26.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
  27. };
  28. #endif
  29.  
  30. #ifdef __MWERKS__
  31. #pragma profile off
  32. #endif
  33.  
  34. static    void    scanFolder(short vRef, long dirID);
  35. static void loadCode(HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header);
  36. short hicall (long cscode, krbHiParmBlock *khipb, short kdriver);
  37.  
  38.  
  39. /*
  40.  * auth_encrypt_init
  41.  * Initialize processing for auth/encrypt options.
  42.  * Find all the modules that support auth/encrypt and add them to our
  43.  * typepairs and modules table. Load those modules and initialize them.
  44.  *
  45.  * Return true if any auth module found.
  46.  */
  47. Boolean auth_encrypt_init ()
  48. {
  49.     short vref;
  50.     long dirid = 0, fold;
  51.     SysEnvRec theWorld;
  52.  
  53.     /*
  54.      * Find and load/initialize files with code modules.
  55.      * First, Try to find the Extensions folder, else use the system folder.
  56.      */
  57.     if (Gestalt('fold', &fold)  || 
  58.         ((fold & 1) != 1) ||
  59.         FindFolder(kOnSystemDisk, kExtensionFolderType, false, &vref, &dirid)) {
  60.         if (SysEnvirons (1, &theWorld) == 0)
  61.             vref = theWorld.sysVRefNum;
  62.         else
  63.             vref = -1;
  64.     }
  65.  
  66.     scanFolder(vref, dirid);
  67.     
  68.     // Now scan the folder that Telnet lives in
  69.     scanFolder(TelInfo->ApFolder.vRefNum, TelInfo->ApFolder.parID);
  70.     
  71.     if (authmodules)
  72.         return true;
  73.     return false;
  74. }
  75.  
  76. static    void    scanFolder(short vRef, long dirID)
  77. {
  78.     short            i;
  79.     HParamBlockRec    pb;
  80.     Str255            name;
  81.     OSErr            s;
  82.     
  83.     for (i = 1; ; i++ ) {
  84.         pb.fileParam.ioCompletion = 0;
  85.         pb.fileParam.ioVRefNum = vRef;
  86.         pb.fileParam.ioFVersNum = 0;
  87.         pb.fileParam.ioFDirIndex = i;
  88.         pb.fileParam.ioDirID = dirID;
  89.         pb.fileParam.ioNamePtr = name;
  90.         if ((s = PBHGetFInfo(&pb, false)) != noErr)
  91.             break;
  92.  
  93.         /*    Check for module types that we are interested in. */
  94.         if (pb.fileParam.ioFlFndrInfo.fdType == moduleType) {
  95.             loadCode(&pb, dirID, name, authType, &authmodules);
  96.             }
  97.         }
  98. }
  99. void loadCode (HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header)
  100. {
  101.     int i;
  102.     short rf, oldrf;
  103.     struct codemodule *code = 0;
  104.     Handle h;
  105.  
  106.     oldrf = CurResFile();
  107.     rf = HOpenResFile(pb->fileParam.ioVRefNum, dirid, name, fsRdPerm);    
  108.     if (rf == -1)
  109.         return;
  110.     SetResLoad(true);
  111.     
  112.     /*
  113.      * Find all resources of indicated type.
  114.      */
  115.     for (i = 1; ; i++) {
  116.         if (!((h = Get1IndResource(type, i))))
  117.             break;
  118.  
  119.         code = (struct codemodule *)myNewPtr(sizeof(struct codemodule));
  120.         if (code) {
  121.             DetachResource(h); 
  122.             HNoPurge(h);
  123.             HLockHi(h);
  124.             code->entry = (module)*h;
  125.             /*
  126.              * Initialize the module.
  127.              * It should preset the type/pairs list and return the number of
  128.              * pairs entered.
  129.              */
  130. #ifdef powerc
  131.             code->npairs = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, 
  132.                                              TNFUNC_INIT_CODE, &code->pairs);
  133.             code->encryptok = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, 
  134.                                                 TNFUNC_QUERY_ENCRYPT, 0);
  135. #else
  136.             code->npairs = (*code->entry)(TNFUNC_INIT_CODE, &code->pairs);
  137.             code->encryptok = (*code->entry)(TNFUNC_QUERY_ENCRYPT, 0);
  138. #endif
  139.             qlink(header, code);
  140.         } else
  141.             ReleaseResource(h);
  142.     }
  143.     CloseResFile(rf);  /* ddd for debugging with The Debugger ***/
  144.     UseResFile(oldrf);
  145. }
  146.  
  147.  
  148. /*
  149.  * auth_suboption
  150.  * Called by the Telnet client when an authentication sub-option is received.
  151.  * The reply option (if any) is placed into sendbuffer and *sendlength adjusted
  152.  * by the amount of data placed into sendbuffer.
  153.  */
  154. void auth_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt)
  155. {
  156.     int i;
  157.     OSErr s;
  158.     unsigned short pair;
  159.     unsigned char *cp, *buflimit;
  160.     struct codemodule *code = 0;
  161.     tnParams *tn;                        /* temp params struct */
  162.     
  163.     buflimit = subbuffer + sublength;
  164.  
  165.     /*
  166.      * Initialize session's tnParams if not initialized yet.
  167.      * Return null auth if no memory and TNQ_SEND.
  168.      */
  169.     if (!(*aedata)) {
  170.         *aedata = (tnParams *)myNewPtr(sizeof(tnParams));
  171.         if (!(*aedata)) {
  172.             if (subbuffer[SB_SUBOPTION] == TNQ_SEND) {
  173.                 BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf));
  174.                 *sendlength -= sizeof(nullbuf);
  175.             }
  176.             return;
  177.         }
  178.     }
  179.     tn = *aedata;
  180.     
  181.     switch (subbuffer[SB_SUBOPTION]) {
  182.     case TNQ_IS:
  183.     case TNQ_NAME:
  184.         /* The client should not get one of these */
  185.         break;
  186.  
  187.     case TNQ_SEND:
  188.         /*
  189.          * For telnet clients, the buffer contains:
  190.          * AUTHENTICATION SEND type modifier [type modifier] [...] IAC SE
  191.          * DDD is IAC SE in the buffer???
  192.          * We scan the type/modifier pairs until we find one we can do. 
  193.          * Since they are are in priority order, the  first one we
  194.          * find that we can do wins.
  195.          */
  196.         for (cp = &subbuffer[SB_TYPE]; cp < buflimit; cp += 2) {
  197.             pair = (cp[0] << 8) | cp[1];
  198.             for (code = authmodules; code; code = code->next) {
  199.                 for (i = 0; i < code->npairs; i++)  {
  200.                     if (pair == code->pairs[i])
  201.                         goto brk;
  202.                 }
  203.             }
  204.         }
  205.     brk:
  206.         if (!code) {
  207.             /*
  208.              * If no methods match, send null authentication.
  209.              */
  210.             BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf));
  211.             *sendlength -= sizeof(nullbuf);
  212.             return;
  213.         }
  214.  
  215.         /*
  216.          * If no auth data, initialize it now.
  217.          */
  218.         if (!(tn->authdata)) {
  219. #ifdef powerc
  220.             s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, 
  221.                                   TNFUNC_INIT_SESSION_AUTH, &tn->authdata);
  222.             if ((s == 0) && !tn->encryptdata)
  223.                 s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, 
  224.                                       TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata);
  225. #else
  226.             s = (*code->entry)(TNFUNC_INIT_SESSION_AUTH, &tn->authdata);
  227.             if ((s == 0) && !tn->encryptdata)
  228.                 s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata);
  229. #endif
  230.             if (s) {                    /* if no memory, etc */
  231.                 BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf));
  232.                 *sendlength -= sizeof(nullbuf);
  233.                 return;
  234.             }
  235.             tn->entry = code->entry;
  236.         }
  237.  
  238.         /*
  239.          * Process the SEND option
  240.          */
  241.         tn->subbuffer = subbuffer;
  242.         tn->sublength = sublength;
  243.         tn->sendbuffer = sendbuffer;
  244.         tn->sendlength = sendlength;
  245.         tn->cname = cname;
  246.         tn->hisencrypt = hisencrypt;
  247.         tn->myencrypt = myencrypt;
  248. #ifdef powerc
  249.         s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, 
  250.                               TNFUNC_AUTH_SEND, tn);        
  251. #else
  252.         s = (*tn->entry)(TNFUNC_AUTH_SEND, tn);
  253. #endif
  254.         if (s) {
  255.             /* ddd null probably wrong here ??? */
  256.             BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf));
  257.             *sendlength -= sizeof(nullbuf);
  258.         }
  259.         return;
  260.  
  261.     case TNQ_REPLY:
  262.         /*
  263.          * Process the reply.
  264.          */
  265.         if (!(tn->authdata)) {
  266.             DebugStr("\pauth_suboption: tnq_reply no authdata");
  267.             return;
  268.         }
  269.         tn->subbuffer = subbuffer;
  270.         tn->sublength = sublength;
  271.         tn->sendbuffer = sendbuffer;
  272.         tn->sendlength = sendlength;
  273.         tn->cname = cname;
  274.         tn->hisencrypt = hisencrypt;
  275.         tn->myencrypt = myencrypt;
  276. #ifdef powerc
  277.         s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, 
  278.                               TNFUNC_AUTH_REPLY, tn);
  279. #else
  280.         s = (*tn->entry)(TNFUNC_AUTH_REPLY, tn);
  281. #endif
  282.         switch (s) {
  283.         case TNREP_OK:
  284.             return;
  285.  
  286.         case TNREP_AUTH_OK:
  287.             break;
  288.  
  289.         case TNREP_AUTH_ERR:
  290.             break;
  291.         }
  292.         return;
  293.     }
  294. }
  295.  
  296.  
  297. /*
  298.  * encrypt_suboption
  299.  * Called by the Telnet client when an encryption sub-option is received.
  300.  * The reply option (if any) is placed into sendbuffer and *sendlength adjusted
  301.  * by the amount of data placed into sendbuffer.
  302.  */
  303. short encrypt_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt)
  304. {
  305.     short s;
  306.     tnParams *tn;
  307.     struct codemodule *code = 0;
  308.             
  309.     /*
  310.      * Initialize session's tnParams if not there. 
  311.      * Return null auth if no memory and TNQ_SEND.
  312.      */
  313.     if (!(*aedata)) {
  314.         *aedata = (tnParams *)myNewPtr(sizeof(tnParams));
  315.         if (!(*aedata)) {
  316.             return 0;
  317.         }
  318.     }
  319.     tn = *aedata;
  320.  
  321.     if (!tn->encryptdata) {
  322.         for (code = authmodules; code; code = code->next) {
  323.             if (code->encryptok)
  324.                 break;
  325.         }
  326.         if (!code)
  327.             return 0;
  328.  
  329. #ifdef powerc
  330.         s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, 
  331.                               TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata);
  332. #else
  333.         s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata);
  334. #endif
  335.         if (s)
  336.             return TNREP_ERROR;
  337.  
  338.         tn->entry = code->entry;
  339.     }
  340.  
  341.     tn->subbuffer = subbuffer;
  342.     tn->sublength = sublength;
  343.     tn->sendbuffer = sendbuffer;
  344.     tn->sendlength = sendlength;
  345.     tn->cname = cname;
  346.     tn->hisencrypt = hisencrypt;
  347.     tn->myencrypt = myencrypt;
  348. #ifdef powerc
  349.     s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, 
  350.                           TNFUNC_ENCRYPT_SB, tn);
  351. #else
  352.     s = (*tn->entry)(TNFUNC_ENCRYPT_SB, tn);
  353. #endif
  354.     return s;
  355. }
  356.  
  357.  
  358. unsigned char decrypt (tnParams *tn, long value)
  359. {
  360.     tn->data = value;
  361. #ifdef powerc
  362.     CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, 
  363.                           TNFUNC_DECRYPT, tn);
  364. #else
  365.     (*tn->entry)(TNFUNC_DECRYPT, tn);
  366. #endif
  367.     return (unsigned char)tn->data;
  368. }
  369.  
  370.  
  371. void encrypt (tnParams *tn, unsigned char *buf, long len)
  372. {
  373.     tn->data = len;
  374.     tn->ebuf = buf;
  375. #ifdef powerc
  376.     CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, 
  377.                           TNFUNC_ENCRYPT, tn);
  378. #else
  379.     (*tn->entry)(TNFUNC_ENCRYPT, tn);
  380. #endif
  381. }
  382.  
  383.  
  384. /*
  385.  * qlink
  386.  * Add an entry to the end of a linked list
  387.  */
  388. void qlink (void **flist, void *fentry)
  389. {
  390.     struct dummy {
  391.         struct dummy *next;
  392.     } **list, *entry;
  393.  
  394.     list = flist;
  395.     entry = fentry;
  396.     
  397.     /*
  398.      * Find address of last entry in the list.
  399.      */
  400.     while (*list)
  401.     list = &(*list)->next;
  402.  
  403.     /*
  404.      * Link entry
  405.      */
  406.     *list = entry;
  407.     entry->next = 0;
  408. }
  409.  
  410.  
  411. /*
  412.  * qunlink
  413.  * Remove an entry from linked list
  414.  * Returns the entry or NULL if not found.
  415.  */
  416. void *qunlink (void **flist, void *fentry)
  417. {
  418.     struct dummy {
  419.         struct dummy *next;
  420.     } **list, *entry;
  421.  
  422.     list = flist;
  423.     entry = fentry;
  424.     
  425.     /*
  426.      * Find entry and unlink it
  427.      */
  428.     while (*list) {
  429.         if ((*list) == entry) {
  430.             *list = entry->next;
  431.             return entry;
  432.         }
  433.     
  434.         list = &(*list)->next;
  435.     }
  436.     return NULL;
  437. }
  438.  
  439.  
  440. short hicall (long cscode, krbHiParmBlock *khipb, short kdriver)
  441. {
  442.     short s;
  443.     ParamBlockRec pb;
  444.     
  445.     WriteZero((Ptr)&pb, sizeof(ParamBlockRec));
  446.     *(long *)pb.cntrlParam.csParam = (long)khipb;
  447.     pb.cntrlParam.ioCompletion = nil;
  448.     pb.cntrlParam.ioCRefNum = kdriver;
  449.  
  450.     pb.cntrlParam.csCode = cscode;
  451.     if (s = PBControl(&pb, false))
  452.         return s;
  453.     if (s = pb.cntrlParam.ioResult)
  454.         return s;
  455.     return 0;
  456. }
  457. void    DestroyTickets(void)
  458. {
  459.     OSErr            err;
  460.     //short authRefNumkrb;
  461.     krbHiParmBlock khpb, *khipb = &khpb;
  462.     short kdriver;
  463.  
  464.     if (!(err = OpenDriver("\p.Kerberos", &kdriver)))
  465.     {
  466.         WriteZero((Ptr)khipb, sizeof(krbHiParmBlock));
  467.         if (err = hicall(cKrbDeleteAllSessions, khipb, kdriver))
  468.             return;
  469.     }
  470.     //else if (!(err=openAuthMan(&authRefNum,&authAPIversion)))
  471.     //    if (err=expireV4Ticket(authRefNum,NULL,NULL,NULL))
  472.     //        return;
  473. }
  474.  
  475.